<template>
  <div class="app-container">
    <!--    表单查询区-->
    <div class="filter-container">
      <el-input v-model="listQuery.key" placeholder="菜单名" style="width: 200px; margin-right: 10px" class="filter-item" clearable @keyup.enter.native="handleFilter" @clear="handleFilter" />
      <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
        搜索
      </el-button>
      <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
        添加
      </el-button>
      <el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">
        导出
      </el-button>
    </div>

    <!--表格区-->
    <el-table
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      row-key="id"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
      border
      fit
      highlight-current-row
      style="width: 100%;"
      @sort-change="sortChange"
    >
      <el-table-column
        label="ID"
        prop="id"
        sortable="custom"
        align="right"
        width="122"
      >
        <template v-slot="{row}">
          <el-tag :type="row.level | levelFilter">{{ row.id }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="菜单名" prop="title" align="center" />
      <el-table-column label="图标" prop="iconName" align="center" width="50px">
        <template v-slot="{row}">
          <item v-if="row.iconName" :icon="row.iconName" />
        </template>
      </el-table-column>
      <!--      <el-table-column label="路由名" prop="name" align="center"/>-->
      <el-table-column label="路由路径" prop="path" align="center" />
      <el-table-column label="组件路径" prop="component" align="center" />
      <el-table-column label="权限编码" prop="permission" align="center" />
      <el-table-column label="权限描述" prop="remarks" align="center" />
      <el-table-column label="状态" class-name="status-col" width="100">
        <template v-slot="{row}">
          <el-switch
            v-model="row.state"
            active-color="#13ce66"
            inactive-color="#ff4949"
            :active-value="0"
            :inactive-value="1"
            @change="handleState(row)"
          />
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
        <template v-slot="{row}">
          <el-button type="primary" size="mini" @click="handleUpdate(row)">
            编辑
          </el-button>
          <el-button size="mini" type="danger" @click="handleDelete(row)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!--分页插件-->
    <pagination v-show="total>0" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />

    <!--添加、编辑权限对话框-->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
      <el-form
        ref="dataForm"
        :rules="rules"
        :model="temp"
        label-position="left"
        label-width="60px"
        style="width: 700px;margin-left: 5px;"
        size="medium"
        @submit.native.prevent
      >
        <el-row :gutter="20">
          <el-col :span="8" class="grid-cell">
            <el-form-item label="菜单名" label-width="80px" prop="title" class="required label-center-align">
              <el-input v-model="temp.title" type="text" placeholder="请输入菜单名" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="10" class="grid-cell">
            <el-form-item label="权限编码" label-width="80px" prop="permission" class="required label-center-align">
              <el-input v-model="temp.permission" type="text" placeholder="请输入权限编码" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="6" class="grid-cell">
            <el-form-item label="权限状态" prop="state" label-width="100px" class="label-center-align">
              <el-switch
                v-model="temp.state"
                :active-value="0"
                :inactive-value="1"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24" class="grid-cell">
            <el-form-item label="权限描述" label-width="80px" prop="remarks" class="label-center-align">
              <el-input v-model="temp.remarks" type="textarea" placeholder="请输入权限描述" rows="1" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12" class="grid-cell">
            <el-form-item label="路由路径" label-width="80px" prop="path" class="required label-center-align">
              <el-input v-model="temp.path" type="text" placeholder="请输入路由路径path" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12" class="grid-cell">
            <el-form-item label="重定向路径" label-width="100px" prop="redirect" class="label-center-align">
              <el-input v-model="temp.redirect" type="text" placeholder="重定向路径redirect" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="9" class="grid-cell">
            <el-form-item label="组件名" label-width="80px" prop="component" class="required label-center-align">
              <el-input v-model="temp.component" type="text" placeholder="组件component" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="10" class="grid-cell">
            <el-form-item label="路由名" label-width="70px" prop="name" class="label-center-align">
              <el-input v-model="temp.name" type="text" placeholder="路由名name" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="5" class="grid-cell">
            <el-form-item label="固定菜单" label-width="70px" prop="alwaysShow" class="label-center-align">
              <el-switch
                v-model="temp.alwaysShow"
                :active-value="true"
                :inactive-value="false"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="9" class="grid-cell">
            <el-form-item label="父权限" label-width="80px" prop="parentId" class="required label-center-align">
              <el-cascader
                v-model="temp.parentId"
                class="full-width-input"
                :options="parentIdOptions"
                :props="{ checkStrictly: true }"
                clearable
                filterable
                placeholder="请选择父权限"
              />
            </el-form-item>
          </el-col>
          <el-col :span="5" class="grid-cell">
            <el-form-item label="图标" label-width="60px" prop="iconName" class="required label-center-align">
              <el-button @click="handleIcon">
                <template v-if="temp.iconName">
                  <i v-if="temp.iconName.includes('el-icon')" :class="temp.iconName" />
                  <svg-icon v-else :icon-class="temp.iconName" />
                </template>
                <i v-else class="el-icon-edit" @click="handleIcon" />
              </el-button>
            </el-form-item>
          </el-col>
          <el-col :span="5" class="grid-cell">
            <el-form-item label="侧边栏隐藏" label-width="90px" prop="hidden" class="label-center-align">
              <el-switch
                v-model="temp.hidden"
                :active-value="true"
                :inactive-value="false"
              />
            </el-form-item>
          </el-col>
          <el-col :span="4" class="grid-cell">
            <el-form-item label="是否缓存" label-width="70px" prop="noCache" class="label-center-align">
              <el-switch
                v-model="temp.noCache"
                :active-value="false"
                :inactive-value="true"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="9" class="grid-cell">
            <el-form-item label="高亮路径" label-width="80px" prop="activeMenu" class="label-center-align">
              <el-input v-model="temp.activeMenu" type="text" placeholder="请输入高亮路径" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="6" class="grid-cell">
            <el-form-item label="面包屑显示" label-width="100px" prop="breadcrumb" class="label-center-align">
              <el-switch
                v-model="temp.breadcrumb"
                :active-value="true"
                :inactive-value="false"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6" class="grid-cell">
            <el-form-item label="面包屑固定" label-width="120px" prop="affix" class="label-center-align">
              <el-switch
                v-model="temp.affix"
                :active-value="true"
                :inactive-value="false"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
          继续
        </el-button>
      </div>
    </el-dialog>

    <!--图标对话框-->
    <el-dialog title="图标选择" width="60%" :visible.sync="dialogIconVisible">
      <icon-select @selectIcon="setIconName" />
    </el-dialog>
  </div>
</template>

<script>
import waves from '@/directive/waves' // waves directive
import Pagination from '@/components/Pagination'
import { createAuth, deleteAuthById, getAuthList, getAuthPage, updateAuth, updateStateById } from '@/api/authority'
import { parseTime } from '@/utils'
import Item from '@/layout/components/Sidebar/Item'
import IconSelect from '@/views/system/authority/component/IconSelect'

// 菜单层级与tag标签定义
const menuLevelOptions = [
  { key: 0, tag_name: 'danger' },
  { key: 1, tag_name: 'success' },
  { key: 2, tag_name: '' }
]

// 菜单层级键值匹配
const menuLevelKeyValue = menuLevelOptions.reduce((acc, cur) => {
  acc[cur.key] = cur.tag_name
  return acc
}, {})

export default {
  name: 'ComplexTable',
  components: { Pagination, Item, IconSelect },
  directives: { waves },
  filters: {
    // 菜单层级过滤
    levelFilter(type) {
      return menuLevelKeyValue[type]
    }
  },
  data() {
    return {
      tableKey: 0,
      list: [],
      total: 0,
      listLoading: true,
      listQuery: {
        current: 1,
        size: 20,
        key: ''
      },
      menuLevelOptions,
      // 表单数据
      temp: {
        id: undefined,
        title: '',
        permission: '',
        redirect: '',
        remarks: '',
        path: '',
        name: '',
        component: '',
        iconName: '',
        activeMenu: '',
        affix: false,
        breadcrumb: true,
        parentId: '',
        state: 0,
        hidden: false,
        alwaysShow: false,
        noCache: true
      },
      // 表单对话框状态控制 true显示  false隐藏
      dialogFormVisible: false,
      // 对话框模式 Create添加 Edit编辑
      dialogStatus: '',
      textMap: {
        update: '编辑',
        create: '添加'
      },
      // 表单校验规则
      rules: {
        title: [{
          required: true,
          message: '菜单名title不能为空'
        }],
        permission: [{
          required: true,
          message: '权限编码不能为空'
        }],
        component: [{
          required: true,
          message: 'component不能为空'
        }],
        name: [{
          required: true,
          message: '路由name不能为空'
        }],
        parentId: [{
          required: true,
          message: '父权限不能为空'
        }]
      },
      // 权限列表
      parentIdOptions: [
        {
          label: '顶级权限',
          value: 10
        }
      ],
      downloadLoading: false,
      dialogIconVisible: false
    }
  },
  created() {
    // 初始化页面请求权限列表
    this.getList()
  },
  methods: {
    // 分页获取权限列表
    getList() {
      // 开启加载渲染
      this.listLoading = true
      getAuthPage(this.listQuery).then(res => {
        this.list = res.data.records
        this.total = res.data.total
        // 关闭加载渲染
        this.listLoading = false
        // 构建级联选择器数据
        this.parentIdOptions = this.buildMenuOptions(this.list)
        const item = {
          'label': '顶级权限',
          'value': 10
        }
        this.parentIdOptions.unshift(item)
      }).catch(() => {
        // 请求错误，关闭加载渲染
        this.listLoading = false
      })
    },
    // 构建菜单选项
    buildMenuOptions(list) {
      const options = []
      list.forEach(item => {
        const menu = {
          'label': item.title,
          'value': item.id
        }
        if (item.children.length > 0) {
          menu.children = this.buildMenuOptions(item.children)
        }
        options.push(menu)
      })
      return options
    },
    // 搜索处理函数
    handleFilter() {
      this.listQuery.current = 1
      this.getList()
    },
    sortChange(data) {
      const { prop, order } = data
      if (prop === 'id') {
        this.sortByID(order)
      }
    },
    // 表单重置
    resetTemp() {
      this.temp = {
        id: undefined,
        title: '',
        permission: '',
        redirect: '',
        remarks: '',
        path: '',
        name: '',
        component: '',
        iconName: '',
        activeMenu: '',
        affix: false,
        breadcrumb: true,
        parentId: '',
        state: 0,
        hidden: false,
        alwaysShow: false,
        noCache: true
      }
    },
    // 添加权限（菜单）
    handleCreate() {
      // 重置表单
      this.resetTemp()
      // 创建对话框
      this.dialogStatus = 'create'
      // 显示对话框
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    // 添加权限函数
    createData() {
      this.temp.parentId = this.temp.parentId[0]
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          createAuth(this.temp).then((res) => {
            this.dialogFormVisible = false
            this.getList()
            this.$notify({
              title: '成功',
              message: res.msg,
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    },
    // 监听更新按钮操作
    handleUpdate(row) {
      this.temp = Object.assign({}, row) // copy obj
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    // 更新权限信息
    updateData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          const tempData = Object.assign({}, this.temp)
          tempData.parentId = tempData.parentId[0]
          tempData.children = []
          updateAuth(tempData).then((res) => {
            this.dialogFormVisible = false
            this.getList()
            this.$notify({
              title: '成功',
              message: res.msg,
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    },
    // 确认删除弹框
    handleDelete(row) {
      this.$confirm('此操作将永久删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.deleteData(row)
      }).catch(() => {
        this.$notify({
          title: '提示',
          message: '已取消删除',
          type: 'info',
          duration: 2000
        })
      })
    },
    // 删除权限信息
    deleteData(row) {
      deleteAuthById(row.id).then(res => {
        this.getList()
        this.$notify({
          title: '成功',
          message: res.msg,
          type: 'success',
          duration: 2000
        })
      })
    },
    // 修改权限状态
    handleState(row) {
      updateStateById(row.id).then(res => {
        this.$notify({
          title: '成功',
          message: res.msg,
          type: 'success',
          duration: 2000
        })
      }).catch(() => {
        row.state = row.state === 1 ? 0 : 1
      })
    },
    handleDownload() {
      this.downloadLoading = true
      getAuthList().then(res => {
        const authorityList = res.data
        import('@/vendor/Export2Excel').then(excel => {
          const tHeader = ['id', 'title', 'iconName', 'path', 'component', 'permission', 'remarks']
          const filterVal = ['id', 'title', 'iconName', 'path', 'component', 'permission', 'remarks']
          const data = this.formatJson(filterVal, authorityList)
          excel.export_json_to_excel({
            header: tHeader,
            data,
            filename: '权限列表' + parseTime(new Date(), '{y}-{m}-{d}-{h}-{i}-{s}')
          })
          this.downloadLoading = false
        })
      })
    },
    formatJson(filterVal, list) {
      return list.map(v => filterVal.map(j => {
        return v[j]
      }))
    },
    // 选组图标对话框监听事件
    handleIcon() {
      this.dialogIconVisible = true
    },
    // 设置菜单图标事件
    setIconName(icon) {
      this.temp.iconName = icon
      this.dialogIconVisible = false
    }
  }
}
</script>
